﻿/*
*类名：Index
*归属：Jjlm命名空间
*用途：实现与微信服务器的对接，处理微信用户发给公众号的信息并给予回应
*作者：乱世刀疤
*日期：2020.05.02
*/

using System;
using System.Web;
using System.Web.Security;
using System.IO;
using System.Xml;
using System.Text;
using QinMing.Config;
using QinMing.Tools;
using QinMing.Weixin.MessageHandlerText;
using QinMing.Weixin.MessageHandlerImage;
using QinMing.Weixin.MessageHandlerVoice;
using QinMing.Weixin.MessageHandlerVideo;
using QinMing.Weixin.MessageHandlerShortVideo;
using QinMing.Weixin.MessageHandlerLocation;
using QinMing.Weixin.MessageHandlerLink;
using QinMing.Weixin.EventHandlerSubscribe;
using QinMing.Weixin.EventHandlerUnSubscribe;
using QinMing.Weixin.EventHandlerLocation;
using QinMing.Weixin.EventHandlerScan;
using QinMing.Weixin.EventHandlerMenuClick;
using QinMing.Weixin.EventHandlerMenuView;

namespace Jjlm
{
	
	public partial class Index : System.Web.UI.Page
	{
		protected void Page_Load(object sender, EventArgs e)
		{
			Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
			string postStr = "";

			if (Request.HttpMethod.ToLower() == "get")
			{
			    Valid();    //首次接入时会验证你的服务器是否能对接上
			}
			else
			{
				Stream s = System.Web.HttpContext.Current.Request.InputStream;
				byte[] b = new byte[s.Length];
				s.Read(b, 0, (int)s.Length);
				postStr = Encoding.UTF8.GetString(b);
				if (!string.IsNullOrEmpty(postStr))
				{
					ResponseMsg(postStr);    //正常交互时的响应和处理
				}
			}
		}
		
		/// <summary>
		/// 返回信息结果(微信信息返回)
		/// </summary>
		/// <param name="weixinXML"></param>
		private void ResponseMsg(string weixinXML)
		{
		   //回复消息的部分:你的代码写在这里
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(weixinXML);
			XmlNodeList list = doc.GetElementsByTagName("xml");
			XmlNode xn = list[0];
			string FromUserName = xn.SelectSingleNode("//FromUserName").InnerText;   //关注用户的加密后openid
			string ToUserName = xn.SelectSingleNode("//ToUserName").InnerText;       //公众微信号原始ID
			string MsgType=xn.SelectSingleNode("//MsgType").InnerText;
			
			//将微信服务器推送的信息保存到log文件中，以便跟踪分析问题，调试时可以打开本开关。
			QinMingTools.WriteLog("公众号推送内容", ConvertXmlToString(doc));
			
			//将微信服务器推送的事件信息保存到weixin_msg_xml_log表中，以便跟踪分析问题
			/*string tmpstr = ConvertXmlToString(doc);
            SqlConnection Conn = new SqlConnection(QinMingConfig.DatabaseConnStr);
			Conn.Open();
			SqlCommand Comm = new SqlCommand();
			Comm.Connection = Conn;
			Comm.CommandText = "insert into weixin_msg_xml_log (FromUserName,ToUserName,MsgType,Event1,EventKey,MsgTime) values("
				+ "'" + FromUserName + "','" + ToUserName + "','" + MsgType + "','" + Event + "','" + EventKey + "',getdate())";
			Comm.ExecuteScalar();
			if (Conn.State == ConnectionState.Open)
			{
				Conn.Close();
				Conn.Dispose();
			}
            */	
			
			if(MsgType == "text")
			{
				//对用户发送的文本消息处理，使用QinMing.Weixin.MessageHandlerText命名空间下的TextMessageDeal类
				TextMessageDeal tmd = new TextMessageDeal();
				Response.Write(tmd.DealResult(weixinXML));
			}
			else if(MsgType == "image")
			{
				//对用户发送的图片消息处理，使用QinMing.Weixin.MessageHandlerImage命名空间下的ImageMessageDeal类
				ImageMessageDeal imd = new ImageMessageDeal();
				Response.Write(imd.DealResult(weixinXML));
			}
			else if(MsgType == "voice")
			{
				//对用户发送的语音消息处理，使用QinMing.Weixin.MessageHandlerVoice命名空间下的VoiceMessageDeal类
				VoiceMessageDeal imd = new VoiceMessageDeal();
				Response.Write(imd.DealResult(weixinXML));
			}
			else if(MsgType == "video")
			{
				//对用户发送的视频消息处理，使用QinMing.Weixin.MessageHandlerVideo命名空间下的VideoMessageDeal类
				VideoMessageDeal vmd = new VideoMessageDeal();
				Response.Write(vmd.DealResult(weixinXML));
			}
			else if(MsgType == "shortvideo")
			{
				//对用户发送的小视频消息处理，使用QinMing.Weixin.MessageHandlerShortVideo命名空间下的ShortVideoMessageDeal类
				ShortVideoMessageDeal svmd = new ShortVideoMessageDeal();
				Response.Write(svmd.DealResult(weixinXML));
			}
			else if(MsgType == "location")
			{
				//对用户发送的位置消息处理，使用QinMing.Weixin.MessageHandlerLocation命名空间下的LocationMessageDeal类
				LocationMessageDeal lcmd = new LocationMessageDeal();
				Response.Write(lcmd.DealResult(weixinXML));				
			}
			else if(MsgType == "link")
			{
				//对用户发送的链接消息处理，使用QinMing.Weixin.MessageHandlerLink命名空间下的LinkMessageDeal类
				LinkMessageDeal lkmd = new LinkMessageDeal();
				Response.Write(lkmd.DealResult(weixinXML));	
			}
			else if(MsgType == "event")  
			{
				string Event = xn.SelectSingleNode("//Event").InnerText;
				if(Event == "subscribe")
				{
					//对用户关注公众号的事件处理，使用QinMing.Weixin.EventHandlerSubscribe命名空间下的SubscribeEventDeal类
					SubscribeEventDeal ued = new SubscribeEventDeal();
					Response.Write(ued.DealResult(weixinXML));	
				}
				else if(Event == "unsubscribe")
				{
					//对用户取消关注公众号的事件处理，使用QinMing.Weixin.EventHandlerUnSubscribe命名空间下的UnSubscribeEventDeal类
					UnSubscribeEventDeal ued = new UnSubscribeEventDeal();
					Response.Write(ued.DealResult(weixinXML));	
				}
				else if(Event == "SCAN")
				{
					//对老用户扫描带参数二维码事件的处理，使用QinMing.Weixin.EventHandlerScan命名空间下的ScanEventDeal类
					ScanEventDeal ued = new ScanEventDeal();
					Response.Write(ued.DealResult(weixinXML));	
				}
				else if(Event == "LOCATION")
				{
					//对用户上报的位置信息事件处理，使用QinMing.Weixin.EventHandlerLocation命名空间下的LocationEventDeal类
					LocationEventDeal ued = new LocationEventDeal();
					Response.Write(ued.DealResult(weixinXML));	
				}
				else if(Event == "CLICK")
				{
					//对用户点击菜单触发的click事件处理，使用QinMing.Weixin.EventHandlerMenuClick命名空间下的MenuClickEventDeal类
					MenuClickEventDeal med = new MenuClickEventDeal();
					Response.Write(med.DealResult(weixinXML));	
				}
				else if(Event == "VIEW")
				{
					//对用户点击菜单触发的VIEW事件处理，使用QinMing.Weixin.EventHandlerMenuView命名空间下的MenuViewEventDeal类
					MenuViewEventDeal med = new MenuViewEventDeal();
					Response.Write(med.DealResult(weixinXML));	
				}
				else if(Event == "TEMPLATESENDJOBFINISH")
				{
					//收到模板消息发送成功的通知后的处理，暂且空值，否则会造成死循环
				}
				else
				{
					//给管理员发送提醒通知
				    QinMing.WeixinTemplateMessage.SendTemplateMessage.SendRemindMsg("orcSBw-hu4YFbm4jN887PZ_8OwLk", "有新类型的事件消息没有处理，请查看日志", "");  
				}
			}
			else
			{
				//给管理员发送提醒通知
				QinMing.WeixinTemplateMessage.SendTemplateMessage.SendRemindMsg("orcSBw-hu4YFbm4jN887PZ_8OwLk", "有新类型的普通消息没有处理，请查看日志", "");  
			}
		}
		 
		/// <summary>
        /// 将XmlDocument转化为string
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <returns></returns>
        public string ConvertXmlToString(XmlDocument xmlDoc)
        {
            MemoryStream stream = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(stream, null);
            writer.Formatting = Formatting.Indented;
            xmlDoc.Save(writer); 
	        StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
            stream.Position = 0;
            string xmlString = sr.ReadToEnd();
            sr.Close();
            stream.Close(); 
	        return xmlString;
		}
 

		/// <summary>
		/// 验证微信签名
		/// </summary>
		/// * 将token、timestamp、nonce三个参数进行字典序排序
		/// * 将三个参数字符串拼接成一个字符串进行sha1加密
		/// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
		/// <returns></returns>
		private bool CheckSignature()
		{
			string signature = Request.QueryString["signature"].ToString();
			string timestamp = Request.QueryString["timestamp"].ToString();
			string nonce = Request.QueryString["nonce"].ToString();
			string[] ArrTmp = { QinMingConfig.Weixin_Token, timestamp, nonce };
			Array.Sort(ArrTmp);     //字典排序
			string tmpStr = string.Join("", ArrTmp);
			tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
			tmpStr = tmpStr.ToLower();
			if (tmpStr.Equals(signature))
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		/// <summary>
		/// 首次接入微信后台时验证
		/// </summary>
		private void Valid()
		{
			string echoStr = Request.QueryString["echoStr"].ToString();
			if (CheckSignature())
			{
				if (!string.IsNullOrEmpty(echoStr))
				{
					Response.Write(echoStr);
					Response.End();
				}
			}
		}
	}

}